﻿/****************************** Module Header ******************************\
 * Module Name:  SessionDataTable.cs
 * Module Version:  1.0.0 (2011-9-30)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is a basic class for the SessionDataTable.  It supplies common public
 * methods to process a internet request, such as Request processing and so on. 
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/

using System;
using System.Data;

namespace UCL.Web
{
    /// <summary>
    /// 会话数据表对象
    /// </summary>
    public class SessionDataTable
    {
        /// <summary>
        /// 返回当前页面的Session对象
        /// </summary>
        private System.Web.SessionState.HttpSessionState httpSession;

        /// <summary>
        /// 当前会话名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 数据表主键标识名称
        /// </summary>
        private int pkIndex;

        /// <summary>
        /// 获取会话中的数据表
        /// </summary>
        public DataTable DataTable { get; private set; }

        /// <summary>
        /// 容量限制
        /// </summary>
        private int maxcount;

        protected SessionDataTable()
        {

        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pkColumnIndex"></param>
        /// <param name="count">最大记录数,0=不限</param>
        public SessionDataTable(string name, int pkColumnIndex = 0, int count = 0)
        {
            this.httpSession = System.Web.HttpContext.Current.Session;
            this.Name = name;
            this.pkIndex = pkColumnIndex;
            object oSess = this.httpSession[name];
            this.maxcount = count;
            this.DataTable = (oSess == null ? (new DataTable()) : (DataTable)oSess);
        }

        #region 架构修改

        /// <summary>
        /// 设置表格列名称
        /// </summary>
        /// <param name="names"></param>
        public void SetColumnsName(params string[] names)
        {
            this.DataTable.SetColumnsName(names);
            this.DataTable.PrimaryKey = new DataColumn[] { DataTable.Columns[pkIndex] };
        }

        /// <summary>
        /// 追加表格列
        /// </summary>
        /// <param name="names"></param>
        public void AppendColumnsName(params string[] names)
        {
            this.DataTable.AppendColumnsName(names);
        }
        #endregion

        #region 特殊查询


        /// <summary>
        /// 获取表格指定列的总和(货币类型)
        /// </summary>
        /// <param name="colIndex"></param>
        /// <returns></returns>
        public double GetSum(int colIndex = 1)
        {
            return this.DataTable.Sum<double>(r => { return r[colIndex]; });
        }

        /// <summary>
        /// 获取表格指定列的总和(整数类型)
        /// </summary>
        /// <param name="colIndex"></param>
        /// <returns></returns>
        public int GetCount(int colIndex = 1)
        {
            return this.DataTable.Sum<int>(r => { return r[colIndex]; });
        }

        /// <summary>
        /// 判断是否为空
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty()
        {
            return this.DataTable.Rows.Count == 0;
        }
        #endregion

        /// <summary>
        /// 添加到会话中的数据表
        /// <para>用于提高批量操作的效率，操作完成后并未保存数据到会话中,需要调用Submit方法来保存数据</para>
        /// <para>主键推荐位于{0}位置</para>
        /// </summary>
        /// <param name="args"></param>
        public void Add(params object[] values)
        {
            this.DataTable.AddRow(this.pkIndex, values);
            if (this.maxcount > 0 && this.DataTable.Rows.Count > this.maxcount) this.DataTable.RemoveByRowIndex(maxcount);
        }

        /// <summary>
        /// 删除指定编号的数据行
        /// <para>用于提高批量操作的效率，操作完成后并未保存数据到会话中,需要调用Submit方法来保存数据</para>
        /// </summary>
        /// <param name="rowid"></param>
        public void RemoveByRowId(int rowid)
        {
            this.DataTable.RemoveByRowIndex(rowid);
        }

        /// <summary>
        /// 删除指定主键的数据
        /// <para>用于提高批量操作的效率，操作完成后并未保存数据到会话中,需要调用Submit方法来保存数据</para>
        /// </summary>
        /// <param name="id"></param>
        public void RemoveById(object id)
        {
            this.DataTable.RemoveByValue(id, this.pkIndex);
        }

        /// <summary>
        /// 判断主键值是否已存在
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Exits(object id)
        {
            return this.DataTable.Exists(id, this.pkIndex);
        }

        /// <summary>
        /// 更新一条数据记录 
        /// <para>用于提高批量操作的效率，操作完成后并未保存数据到会话中,需要调用Submit方法来保存数据</para>
        /// </summary>
        /// <param name="rowId"></param>
        /// <param name="colsIndex"></param>
        /// <param name="values"></param>
        public void UpdateByRowIdCache(int rowId, int[] colsIndex, params object[] values)
        {
            this.DataTable.UpdateByRowIndex(rowId, colsIndex, values);
        }

        /// <summary>
        /// 保存数据表到会话中
        /// </summary>
        public void Save()
        {
            this.httpSession[this.Name] = this.DataTable;
        }

        /// <summary>
        /// 清除当前会话对象
        /// </summary>
        public void Clear()
        {
            if (this.httpSession[this.Name] == null) return;
            this.httpSession[this.Name] = null;
        }

        /// <summary>
        /// 更新包含指定主键值的某行某列的值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="colName"></param>
        /// <param name="v"></param>
        public void Update(object id, string colName, object v)
        {
            DataRow r = this.DataTable.Rows.Find(id);
            if (r == null) return;
            this.DataTable.Rows[this.DataTable.Rows.IndexOf(r)][colName] = v;
        }

        public object GetValue(int rowId, string colName)
        {
            return this.DataTable.Rows[rowId][colName];
        }
    }
}
